package com.faxsun.profile.core.service;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.broadleafcommerce.common.util.TransactionUtils;
import org.broadleafcommerce.core.pricing.service.exception.PricingException;
import org.broadleafcommerce.profile.core.domain.Customer;
import org.broadleafcommerce.profile.core.service.CustomerService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.faxsun.profile.core.dao.FSThirdPartyCustomerDao;
import com.faxsun.profile.core.domain.FSCustomer;
import com.faxsun.profile.core.domain.FSThirdPartyCustomer;
import com.faxsun.profile.core.exception.AccountBindedThirdAccountException;
import com.faxsun.profile.core.exception.ThirdAccountBindToMultipleAccountException;
import com.faxsun.profile.core.exception.ThirdAccountBindedException;

public class FSThirdPartyCustomerServiceImpl implements FSThirdPartyCustomerService {

	private static final Log LOG = LogFactory.getLog(FSThirdPartyCustomerServiceImpl.class);

	@Resource(name = "blThirdPartyCustomerDao")
	protected FSThirdPartyCustomerDao customer3thDao;

	@Resource(name = "blCustomerService")
	CustomerService customerService;

	@Override
	@Transactional(TransactionUtils.DEFAULT_TRANSACTION_MANAGER)
	public FSThirdPartyCustomer create3thCustomerByUid(String uid) {
		return customer3thDao.create3thCustomerByUid(uid);
	}

	@Override
	public boolean checkCustomerBy3thUid(String uid) {
		return customer3thDao.check3thCustomerByUid(uid);
	}

	@Override
	public FSCustomer getCustomerByUid(String uid) {
		List<FSCustomer> customerList = customer3thDao.readCustomerBy3thUid(uid);
		return customerList == null || customerList.isEmpty() ? null : customerList.get(0);
	}

	@Override
	@Transactional(TransactionUtils.DEFAULT_TRANSACTION_MANAGER)
	public FSThirdPartyCustomer save(FSThirdPartyCustomer fscustomer3th) {
		return customer3thDao.save(fscustomer3th);
	}

	@Override
	@Transactional(TransactionUtils.DEFAULT_TRANSACTION_MANAGER)
	public boolean bindAccount(String channelId, String uid, Long id, String password, boolean isPasswordLogin,
			String unionId, String avatar, String nickname) throws ThirdAccountBindedException,
					ThirdAccountBindToMultipleAccountException, AccountBindedThirdAccountException {
		Customer customer = customerService.readCustomerById(id);
		boolean ret = false;
		if (StringUtils.isEmpty(uid)) {
			return ret;
		}
		if (isPasswordLogin || customerService.isPasswordValid(password, customer.getPassword(), customer)) {
			// 用户已登录或者密码验证通过

			// 检查当前帐户是否已绑定微信
			FSThirdPartyCustomer thirdCustomer = customer3thDao.findCustomer3thByCustomerAndChannel(id, channelId);
			if (thirdCustomer != null) {
				throw new AccountBindedThirdAccountException(String.valueOf(id));
			}

			// 检查uid是否已与其他帐户绑定
			List<FSCustomer> customers = customer3thDao.readCustomerBy3thUid(uid);
			if (customers.size() > 1) {
				// 绑定到多个帐户
				LOG.error("OpenId=" + uid + " bind to multiply account");
				throw new ThirdAccountBindToMultipleAccountException(uid);
			} else if (customers.size() == 1) {
				// 已绑定
				if (customers.get(0).getId().equals(id)) {
					LOG.error("It is imposible to enter this branch: binded account request to bind openId=" + uid
							+ " again!");

				} else {
					// check the customer has been bind?
					if (customers.get(0).isBindedToEmail()) {
						// request to bind to another account which has bind the
						// third account, throw exception for
						// ThirdAccountBindedException
						throw new ThirdAccountBindedException(uid);
					} else {
						// 绑定一个已存在帐户，满足条件，进行合并绑定
						try {
							((FSCustomerService) customerService).mergeCustomers(customers.get(0), customer);
							ret = true;
						} catch (PricingException e) {
							LOG.error("", e);
							ret = false;
						}

					}
				}
			} else {
				// 未绑定
				// 执行绑定
				FSThirdPartyCustomer customer3th = create3thCustomerByUid(uid);
				customer3th.setChannelId(channelId);
				customer3th.setCustomer(customer);
				if (!StringUtils.isEmpty(unionId)) {
					customer3th.setUnionId(unionId);
				}
				if (!StringUtils.isEmpty(avatar)) {
					customer3th.setAvatar(avatar);
				}
				if (!StringUtils.isEmpty(nickname)) {
					customer3th.setNickName(nickname);
				}

				save(customer3th);
				ret = true;
			}

		}
		return ret;
	}

	@Override
	public List<FSThirdPartyCustomer> readThirdPartyCustomerForCustomer(Customer customer) {
		return customer3thDao.readThirdPartyCustomerForCustomer(customer.getId());
	}

	@Override
	public FSThirdPartyCustomer getCustomer3thByUid(String uid) {
		return customer3thDao.readCustomer3thByUid(uid);
	}

	@Override
	@Transactional(TransactionUtils.DEFAULT_TRANSACTION_MANAGER)
	public void unbind(long customerId, String channelId) {
		FSThirdPartyCustomer customer3th = customer3thDao.findCustomer3thByCustomerAndChannel(customerId, channelId);
		if (customer3th != null)
			this.customer3thDao.delete(customer3th);

	}

	@Override
	public FSCustomer getCustomer3thByUnionid(String unionid) {
		FSCustomer customer = customer3thDao.findCustomer3thByUnionId(unionid);
		return customer;
	}

	@Override
	public boolean checkCustomerBy3thUnionid(String unionid) {
		// TODO Auto-generated method stub
		return false;
	}

}
